package userservice

import (
	"context"
	"gitee.com/go-mid/infra/xcore"
	"gitee.com/go-mid/infra/xsql/xdb"
	"gitee.com/go-mid/user/internal/component"
	"gitee.com/go-mid/user/internal/entity"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

//获取不到，则返回的userId为0
//注意：同一个loginid 只能有一个userId（db通过唯一索引保证的）
func (m *UserServiceImpl) getUserIdByLoginid(ctx context.Context, loginID LoginID) (int64, error) {
	item, err := m.getLoginid(ctx, loginID)
	if err != nil {
		return 0, err
	}
	var userId int64
	if item != nil {
		userId = item.UserID
	}
	return userId, nil
}
func (m *UserServiceImpl) getLoginid(ctx context.Context, loginID LoginID) (*entity.UserLoginid, error) {
	loginid, loginidType := loginID.Loginid, loginID.LoginidType
	loginid = m.encryLoginid(ctx, loginID)
	var item entity.UserLoginid
	err := component.XDBUser.SelectOne(ctx, entity.UserLoginidTable, map[string]interface{}{
		"loginid":      loginid,
		"loginid_type": loginidType,
		"user_pool_id": loginID.UserPoolID,
	}, &item)
	if xdb.IsNotFound(err) {
		return nil, nil
	}
	if err != nil {
		return nil, status.Error(codes.Internal, err.Error())
	}
	if item.Loginid != "" {
		//解密
		item.Loginid = m.decryLoginid(ctx, LoginID{
			LoginidType: EnumLoginidType(item.LoginidType),
			Loginid:     item.Loginid,
			UserPoolID:  item.UserPoolID,
			Appid:       item.Appid,
		})
	}
	return &item, nil
}

//一个用户有可能有多个loginid, 比如： 用户有手机号、也有微信
func (m *UserServiceImpl) listLoginidByUserId(ctx context.Context, userId int64, userPoolID int64, loginidType EnumLoginidType) ([]*entity.UserLoginid, error) {
	var items []*entity.UserLoginid
	where := map[string]interface{}{
		"user_id":      userId,
		"user_pool_id": userPoolID,
	}
	if loginidType != 0 {
		where["loginid_type"] = loginidType
	}
	err := component.XDBUser.Select(ctx, entity.UserLoginidTable, where, &items)
	if err != nil {
		return nil, status.Error(codes.Internal, err.Error())
	}
	for _, item := range items {
		//解密
		item.Loginid = m.decryLoginid(ctx, LoginID{
			LoginidType: EnumLoginidType(item.LoginidType),
			Loginid:     item.Loginid,
			UserPoolID:  item.UserPoolID,
			Appid:       item.Appid,
		})
	}
	return items, err
}

//一个用户有可能有多个loginid, 比如： 用户有手机号、也有微信
func (m *UserServiceImpl) batchListLoginidByUserId(ctx context.Context, userIds []int64, userPoolID int64, loginidType EnumLoginidType) ([]*entity.UserLoginid, error) {
	var items []*entity.UserLoginid
	where := map[string]interface{}{
		"user_id in ":  userIds,
		"user_pool_id": userPoolID,
	}
	if loginidType != 0 {
		where["loginid_type"] = loginidType
	}
	err := component.XDBUser.Select(ctx, entity.UserLoginidTable, where, &items)
	if err != nil {
		return nil, status.Error(codes.Internal, err.Error())
	}
	for _, item := range items {
		//解密
		item.Loginid = m.decryLoginid(ctx, LoginID{
			LoginidType: EnumLoginidType(item.LoginidType),
			Loginid:     item.Loginid,
			UserPoolID:  item.UserPoolID,
			Appid:       item.Appid,
		})
	}
	return items, err
}

func (m *UserServiceImpl) encryLoginid(ctx context.Context, logindID LoginID) string {
	loginid, loginidType := logindID.Loginid, logindID.LoginidType
	switch loginidType {
	case EnumLoginidType_PHONE:
		salt, iv := getEncryKey(ctx)
		loginid = xcore.WorldPhoneFmt(ctx, loginid)
		loginid = xcore.Encode(ctx, loginid, salt, iv)
	}
	return loginid
}

func (m *UserServiceImpl) decryLoginid(ctx context.Context, logindID LoginID) string {
	loginid, loginidType := logindID.Loginid, logindID.LoginidType
	switch loginidType {
	case EnumLoginidType_PHONE:
		salt, iv := getEncryKey(ctx)
		loginid = xcore.Decode(ctx, loginid, salt, iv)
	}
	return loginid
}
func getEncryKey(ctx context.Context) (string, string) {
	return "f7a42fe7211f98ac", "f0b53b2da041fca4"
}
